﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text;
using System.Net;
using System.Collections.Specialized;
using System.IO;
using System.Xml;

using Factonomy.AzureUtility.Core.Storage;
using Factonomy.AzureUtility.Core.Storage.StorageHttpConstants;

namespace Factonomy.AzureUtility.Core.StorageHelpers
{
    class TableHelper
    {
        private Uri _liveBaseUri = new Uri("http://table.core.windows.net");
        private Uri _devBaseUri = new Uri("http://127.0.0.1:10002");
        private static TableHelper _instance;

        public static TableHelper Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new TableHelper();
                }
                return _instance;
            }
        }

        private StorageAccountInfo GetTableStorage(ConfigAccount account)
        {
            StorageAccountInfo storageAccount = new StorageAccountInfo(account.Local ? this._devBaseUri : this._liveBaseUri, account.Local, account.AccountName, account.SharedKey);
            return storageAccount;
        }

        public XmlNamespaceManager CreateXmlNameSpaceManager(XmlNameTable nameTable)
        {
            XmlNamespaceManager manager = new XmlNamespaceManager(nameTable);
            manager.AddNamespace("d", "http://schemas.microsoft.com/ado/2007/08/dataservices");
            manager.AddNamespace("m", "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata");
            manager.AddNamespace("a", "http://www.w3.org/2005/Atom");
            return manager;
        }

        public void CreateTable(ConfigAccount account, string tableName)
        {
            StorageAccountInfo storageAccount = this.GetTableStorage(account);
        }

        public List<string> ListTables(ConfigAccount account)
        {
            try
            {
                List<string> list = new List<string>();

                StorageAccountInfo storageAccount = this.GetTableStorage(account);
                string uri = StorageAccountInfo.BuildUri(storageAccount.BaseUri.ToString(), account.AccountName, "Tables()", "", account.Local);

                HttpWebRequest request = HttpWebRequest.Create(uri) as HttpWebRequest;
                request.KeepAlive = true;

                byte[] key = Convert.FromBase64String(storageAccount.Base64Key);
                SharedKeyCredentials credentials = new SharedKeyCredentials(account.AccountName, key);
                credentials.SignRequestForSharedKeyLite(request, new ResourceUriComponents(account.AccountName, account.AccountName));

                HttpWebResponse response = request.GetResponse() as HttpWebResponse;
                XmlDocument doc = new XmlDocument();

                XmlNamespaceManager manager = this.CreateXmlNameSpaceManager(doc.NameTable);

                using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                {
                    doc.LoadXml(reader.ReadToEnd());

                    foreach (XmlNode entry in doc.DocumentElement.SelectNodes("a:entry/a:content/m:properties/d:TableName", manager))
                    {
                        list.Add(entry.InnerText);
                    }
                }

                return list;
            }
            catch (WebException ex)
            {
                return null;
            }
        }
    }
}
